home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / Everex.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  243 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/Everex.c++,v 1.42 1994/04/08 03:49:33 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include "Everex.h"
  26. #include "ModemConfig.h"
  27.  
  28. #include "everex.h"
  29. #include "t.30.h"
  30.  
  31. #include <stdlib.h>
  32.  
  33. /*
  34.  * Everex Modem Driver.
  35.  */
  36. EverexModem::EverexModem(FaxServer& s, const ModemConfig& c) : FaxModem(s,c)
  37. {
  38.     type = UNKNOWN;
  39. }
  40.  
  41. EverexModem::~EverexModem()
  42. {
  43. }
  44.  
  45. fxBool
  46. EverexModem::dataService()
  47. {
  48.     return (FALSE);
  49. }
  50.  
  51. #define    isCapable(what)        (capabilities & BIT(what))
  52.  
  53. fxBool
  54. EverexModem::setupModem()
  55. {
  56.     if (!selectBaudRate(EVEREX_CMDBRATE, FLOW_XONXOFF, FLOW_XONXOFF))
  57.     return (FALSE);
  58.     type = UNKNOWN;
  59.     if (atCmd("I4?", AT_NOTHING) && atResponse(rbuf) == AT_OTHER) {
  60.     modemModel = rbuf;
  61.     type = (modemModel == "EV958") ? EV958
  62.          : (modemModel == "EV968") ? EV968
  63.          :                      ABATON;    // generic
  64.     modemMfr = "Everex";
  65.     (void) sync(500);
  66.     }
  67.     if (type == UNKNOWN)
  68.     return (FALSE);
  69.     if (conf.flowControl != FLOW_XONXOFF) {
  70.     serverTrace("Sorry, Everex driver requires XON/XOFF flow control");
  71.     return (FALSE);
  72.     }
  73.     // get modem capabilities bit mask
  74.     u_int capabilities;
  75.     if (atCmd("#S3?", AT_NOTHING) && atResponse(rbuf) == AT_OTHER) {
  76.     capabilities = fromHex(rbuf);
  77.     (void) sync(500);
  78.     } else
  79.     return (FALSE);
  80.     if (atCmd("I7?", AT_NOTHING) && atResponse(rbuf) == AT_OTHER) {
  81.     modemRevision = rbuf;
  82.     (void) sync(500);
  83.     }
  84.     modemServices = SERVICE_DATA|SERVICE_CLASS1;    // XXX bit of a cheat
  85.     modemParams.vr = VR_ALL;
  86.     modemParams.br = 0;
  87.     if (isCapable(S4_9600V29))
  88.     modemParams.br |= BIT(BR_9600);
  89.     if (isCapable(S4_7200V29))
  90.     modemParams.br |= BIT(BR_7200);
  91.     if (isCapable(S4_4800V27) || isCapable(S4_4800V29))
  92.     modemParams.br |= BIT(BR_4800);
  93.     if (isCapable(S4_2400V27))
  94.     modemParams.br |= BIT(BR_2400);
  95.     modemParams.wd = BIT(WD_1728) | BIT(WD_2048) | BIT(WD_2432);
  96.     modemParams.ln = LN_ALL;
  97.     modemParams.df = BIT(DF_1DMR) | BIT(DF_2DMR);
  98.     modemParams.ec = 0;
  99.     modemParams.bf = 0;
  100.     modemParams.st = ST_ALL;
  101.     traceBits(modemServices, serviceNames);
  102.     traceModemParams();
  103.     return TRUE;
  104. }
  105.  
  106. fxBool
  107. EverexModem::supportsEOLPadding() const    
  108. {
  109.     return TRUE;
  110. }
  111.  
  112. void
  113. EverexModem::setLID(const fxStr& number)
  114. {
  115.     encodeCSI(lid, number);
  116. }
  117.  
  118. /*
  119.  * Construct a Calling Station Identifier (CSI) string
  120.  * for the modem.  This is encoded as a string of hex digits
  121.  * according to Table 3/T.30 (see the spec).  Hyphen ('-')
  122.  * and period are converted to space; otherwise invalid
  123.  * characters are ignored in the conversion.  The string may
  124.  * be at most 20 characters (according to the spec).
  125.  */
  126. void
  127. EverexModem::encodeCSI(fxStr& binary, const fxStr& ascii)
  128. {
  129.     char buf[40];
  130.     const char* hexDigits = "0123456789ABCDEF";
  131.     u_int n = fxmin(ascii.length(),(u_int) 20);
  132.     for (u_int i = 0, j = 0; i < n; i++) {
  133.     int c = ascii[i];
  134.     for (const u_char* dp = digitMap; *dp; dp += 2)
  135.         if (c == dp[1]) {
  136.         buf[j++] = hexDigits[dp[0]>>4];
  137.         buf[j++] = hexDigits[dp[0]&0xf];
  138.         break;
  139.         }
  140.     }
  141.     /*
  142.      * Now ``reverse copy'' the string.
  143.      */
  144.     binary.resize(40);
  145.     for (i = 0; j > 1; i += 2, j -= 2) {
  146.     binary[i] = buf[j-2];
  147.     binary[i+1] = buf[j-1];
  148.     }
  149.     for (; i < 40; i+= 2)
  150.     binary[i] = '0', binary[i+1] = '4';    // blank pad remainder
  151. }
  152.  
  153. /*
  154.  * Do the inverse of encodeCSI; i.e. convert a string of
  155.  * hex digits from the modem into the equivalent ASCII.
  156.  */
  157. void
  158. EverexModem::decodeCSI(fxStr& ascii, const fxStr& binary)
  159. {
  160.     int n = binary.length();
  161.     if (n > 40)        // spec says no more than 20 digits
  162.     n = 40;
  163.     ascii.resize((n+1)/2);
  164.     u_int d = 0;
  165.     fxBool seenDigit = FALSE;
  166.     for (char* cp = (char *)binary + n-2; n > 1; cp -= 2, n -= 2) {
  167.        int digit = fromHex(cp, 2);
  168.        for (const u_char* dp = digitMap; *dp != '\0'; dp += 2)
  169.         if (dp[0] == digit) {
  170.         if (dp[1] != ' ')
  171.             seenDigit = TRUE;
  172.         if (seenDigit)
  173.             ascii[d++] = dp[1];
  174.         break;
  175.         }
  176.     }
  177.     ascii.resize(d);
  178. }
  179.  
  180. fxBool
  181. EverexModem::sendFrame(int f1)
  182. {
  183.     return (atCmd("#FT=" | toHex(f1,2)));
  184. }
  185.  
  186. fxBool
  187. EverexModem::sendFrame(int f1, int f2)
  188. {
  189.     return (atCmd("#FT=" | toHex(f1,2) | toHex(f2,2)));
  190. }
  191.  
  192. fxBool
  193. EverexModem::sendFrame(int f1, int f2, int f3)
  194. {
  195.     return (atCmd("#FT=" | toHex(f1,2) | toHex(f2,2) | toHex(f3,2)));
  196. }
  197.  
  198. fxBool
  199. EverexModem::setupFrame(int f, int v)
  200. {
  201.     return (atCmd("#FT" | toHex(f, 2) | "=" | toHex(v, 8)));
  202. }
  203.  
  204. fxBool
  205. EverexModem::setupFrame(int f, const char* v)
  206. {
  207.     return (atCmd("#FT" | toHex(f, 2) | "=" | v));
  208. }
  209.  
  210. fxBool
  211. EverexModem::recvFrame(long ms)
  212. {
  213.     return (getModemLine(rbuf, sizeof (rbuf), ms) > 2 && strneq(rbuf, "R ", 2));
  214. }
  215.  
  216. /* 
  217.  * Modem manipulation support.
  218.  */
  219.  
  220. fxBool
  221. EverexModem::reset(long ms)
  222. {
  223.     // &C0    DCD always on
  224.     // &D3    force modem reset when DTR is toggled
  225.     // #V    enable verbose codes
  226.     // #Z    reset fax state
  227.     return (FaxModem::reset(ms) && atCmd("&C0&D3#V#Z"));
  228. }
  229.  
  230. fxBool
  231. EverexModem::abort(long ms)
  232. {
  233.     // XXX maybe should not always send DCN
  234.     sendFrame(FCF_DCN|FCF_SNDR);        // terminate session
  235.     return (atCmd("#ZH0", AT_OK, ms));
  236. }
  237.  
  238. fxBool
  239. EverexModem::modemFaxConfigure(int bits)
  240. {
  241.     return (atCmd("#S2=" | fxStr(bits, "%d")));
  242. }
  243.